package com.cqhilink.iot.jobstandardmanagement.services.innerservice.impl.operateunit;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cqhilink.api.common.utils.UniqueUtil;
import com.cqhilink.api.common.utils.date.DateStyle;
import com.cqhilink.api.common.utils.date.DateUtil;
import com.cqhilink.api.common.utils.enums.RespCodeEnum;
import com.cqhilink.iot.jobstandardmanagement.dao.mapper.*;
import com.cqhilink.iot.jobstandardmanagement.facade.model.*;
import com.cqhilink.iot.jobstandardmanagement.facade.service.file.JsmFileService;
import com.cqhilink.iot.jobstandardmanagement.facade.service.operateunit.JsmOperateUnitService;
import com.cqhilink.iot.jobstandardmanagement.facade.service.singlework.JsmSingleWorkService;
import com.cqhilink.iot.jobstandardmanagement.facade.service.version.JsmVersionService;
import com.cqhilink.iot.jobstandardmanagement.facade.utils.BackMessage;
import com.cqhilink.iot.jobstandardmanagement.facade.utils.StepStage;
import com.cqhilink.iot.jobstandardmanagement.facade.utils.poi.Step.StepPic;
import com.cqhilink.iot.jobstandardmanagement.services.innerservice.JsmUploadService;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.math.BigDecimal;
import java.util.*;

/**
 * Created by YuPeng on 2017/1/7.
 * modify huangxueqian on 2017/02/13 add新增版本控制问题
 * 将版本控制集中处理
 * modify by huangxueqian on 2017/8/14 add新增版本控制问题
 */

public class JsmOperateUnitServiceImpl implements JsmOperateUnitService {

    @Autowired
    private JsmVersionService versionService ;
    @Autowired
    private JsmSingleWorkService singleWorkService;
    @Autowired
    private WorkCellInfoMapper workCellInfoMapper;
    @Autowired
    private WorkCellInstanceMapper workCellInstanceMapper;
    @Autowired
    private JsmFileService fileService ;
    @Autowired
    private FileMapper fileMapper;
    @Autowired
    private SingleWorkStepDataItemMapper singleWorkStepDataItemMapper;
    @Autowired
    private SingleWorkStepMapper singleWorkStepMapper;

    @Autowired
    private JsmUploadService uploadService;


    @Autowired
    private ApplicationContext applicationContext;

    /**
     * 操作步骤列表获取；一站一案配置中；添加
     * @param singleWorkStep
     */
    @Override
    public JSONObject getStep(SingleWorkStep singleWorkStep) throws Exception {
        JSONObject jsonObject = new JSONObject();
        if (!StringUtils.isBlank(singleWorkStep.getCellId())) {
            //获取工作内容对象
            WorkCellInfo workCell = getWorkCell(singleWorkStep.getCellId());
            if (workCell.getStepVersion() != null) {
                singleWorkStep.setVersion(workCell.getStepVersion());
            }
            //设置按操作单元进行查询
                List<SingleWorkStep> stepList = singleWorkStepMapper.selectByStep(singleWorkStep);
                if(stepList!=null){
                    setParentName(stepList);
                    jsonObject.put("rows", JSON.toJSON(stepList));
            }
        }
        return jsonObject;
    }

    /**
     * 获取单个步骤对象
     *
     * @param stepId
     * @return
     * @throws Exception
     */
    @Override
    public SingleWorkStep getStep(String stepId) throws Exception {
        return stepId == null ? null : singleWorkStepMapper.selectByPrimaryKey(stepId);
    }

    /**
     * @param workCellInfoId 操作单元内容
     */
    private WorkCellInfo getWorkCell(String workCellInfoId) {
        WorkCellInfo workCellInfo = workCellInfoMapper.selectByPrimaryKey(workCellInfoId);
        return workCellInfo;
    }

    /**
     * 新增步骤
     * @param singleWorkStep 步骤数据
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Map<String, Object> addStep(SingleWorkStep singleWorkStep,Employee employee) throws Exception {
        singleWorkStep.setStepId(UniqueUtil.uuid());
        String creatorId = employee.getEmployeeId();
        Map<String, Object> map = isBlank(singleWorkStep);
        //对参数进行判空
        if ((Boolean) map.get("state") == RespCodeEnum.RESP_CODE_ENUM_false.code()) {
            return map;
        }
        singleWorkStep.setCreatorId(creatorId);
        singleWorkStep.setCreateTime(DateUtil.getTimeString());
        /**
         * 新增步骤时，如果是插入步骤存在步骤号，步骤号就是索引号
         */
        if (singleWorkStep.getStepIndex() != null) {
            map = insertStep(singleWorkStep);
        } else {
            map = addStepNormal(singleWorkStep);
        }
        /**
         * 操作步骤-新增
         */
        try {
            fileService.addFile(singleWorkStep.getUploadFiles(),singleWorkStep.getDeletedFiles(),singleWorkStep.getStepId());
        } catch (Exception e) {
            e.printStackTrace();
        }

        return map;
    }

    /**
     * 正常添加步骤
     *
     * @param singleWorkStep
     * @return
     * @throws Exception
     */
    private Map<String, Object> addStepNormal(SingleWorkStep singleWorkStep) throws Exception {
        Map<String, Object> map = new HashMap<>();
        SingleWorkStep step = new SingleWorkStep();
        step.setCellId(singleWorkStep.getCellId());
        int maxIndex = singleWorkStepMapper.selectCountByStep(singleWorkStep);
        singleWorkStep.setStepIndex(maxIndex + 1);
        int num = singleWorkStepMapper.insertSelective(singleWorkStep);
        map.put("state", num > 0 ? RespCodeEnum.RESP_CODE_ENUM_true.code() : RespCodeEnum.RESP_CODE_ENUM_false.code());
        map.put("msg", num > 0 ? BackMessage.ADD_OK : BackMessage.ADD_FAIL);
        return map;
    }

    /**
     * 用于插入式添加步骤
     * 插入步骤的顺序应该是，将获取比当前步骤号大的然后，顺序+1后子进行新增 ；
     * @param singleWorkStep 步骤数据
     */
    @Transactional(propagation = Propagation.REQUIRED)
    private Map<String, Object> insertStep(SingleWorkStep singleWorkStep) throws Exception {
        /**
         * 获取操作单元，获取操作步比大的序列号大；
         */
        Map<String, Object> map = new HashMap<>();
        try {
            int index = singleWorkStep.getStepIndex();
            List<SingleWorkStep> nextStepList = getNextSteps(singleWorkStep);
            // 数据非空判断
            if(nextStepList != null && nextStepList.size() > 0){
                for (SingleWorkStep singleWorkStep1 : nextStepList){
                    index ++ ;
                    singleWorkStep1.setStepIndex(index);
                    singleWorkStepMapper.updateByPrimaryKeySelective(singleWorkStep1);
                }
            }
            // 步骤新增插入// 步骤新增插入
            singleWorkStepMapper.insertSelective(singleWorkStep);
            map.put("state", RespCodeEnum.RESP_CODE_ENUM_true.code());
            map.put("msg", BackMessage.ADD_OK);
        } catch (Exception e) {
            map.put("state", RespCodeEnum.RESP_CODE_ENUM_false.code());
            map.put("msg", BackMessage.ADD_FAIL);
            e.printStackTrace();
        }
        return map;
    }


    /**
     * 获取当前步骤之后的步骤
     * @param singleWorkStep
     * @return
     */
    private List<SingleWorkStep> getNextSteps(SingleWorkStep singleWorkStep){

        return singleWorkStepMapper.selectByBigThanIndexByCellId(singleWorkStep);
    }


    /**
     * 修改步骤
     * @param singleWorkStep
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Map<String, Object> modifyStep(SingleWorkStep singleWorkStep,Employee employee) throws Exception {
        Map<String, Object> map = isBlank(singleWorkStep);
        String modifierId = employee.getEmployeeId();
        if ((Boolean) map.get("state") == RespCodeEnum.RESP_CODE_ENUM_false.code()) {
            return map;
        }
        singleWorkStep.setModifierId(modifierId);
        singleWorkStep.setModifyTime(DateUtil.getTimeString());
        int num = singleWorkStepMapper.updateByPrimaryKeySelective(singleWorkStep);
        map.put("state", num > 0 ? RespCodeEnum.RESP_CODE_ENUM_true.code() : RespCodeEnum.RESP_CODE_ENUM_false.code());
        map.put("msg", num > 0 ? BackMessage.MODIFY_OK : BackMessage.MODIFY_FAIL);
        try {
            fileService.addFile(singleWorkStep.getStepId(),singleWorkStep.getUploadFiles(),singleWorkStep.getDeletedFiles());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 删除单个步骤
     *
     * @param stepId
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Map<String, Object> delStep(String stepId) throws Exception {
        return singleWorkService.del(stepId);
    }

    /**
     * 批量删除步骤
     *
     * @param stepIds
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Map<String, Object> delStepBatch(String[] stepIds, String cellId) throws Exception {
        Map<String, Object> map = new HashedMap();
        if (stepIds == null || stepIds.length == 0) {
            map.put("state", RespCodeEnum.RESP_CODE_ENUM_false.code());
            map.put("msg", BackMessage.EMPTY_PARAMETER);
            return map;
        }
        List<String> stepList = new ArrayList<>();
        for (int i = 0; i < stepIds.length; i++) {
            stepList.add(stepIds[i]);
        }
        if (singleWorkStepMapper.updateStatusBatch(stepList) > 0) {
            List<SingleWorkStep> steplist = singleWorkStepMapper.selectByStepSelect(new SingleWorkStep(cellId, null));
            singleWorkService.resortStep(steplist);
            map.put("state", RespCodeEnum.RESP_CODE_ENUM_true.code());
            map.put("msg", BackMessage.DEL_OK);
            return map;
        }
        map.put("state", RespCodeEnum.RESP_CODE_ENUM_false.code());
        map.put("msg", BackMessage.DEL_FAIL);
        return map;
    }

    /**
     *
     * @param stepIds 操作步骤，将选择的内容复制到新的版本中去
     * @param versionNumber
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Map<String, Object> insertStepVersion(String stepIds, BigDecimal versionNumber) throws Exception {
        Map<String, Object> resMap = new HashMap<>();
        List<SingleWorkStep> singleWorkSteps = new ArrayList<>();
        if(stepIds!=null){
            List<String> list = JSON.parseArray(stepIds,String.class);
            for(String  stepId : list){
                SingleWorkStep singleWorkStep = singleWorkStepMapper.selectByPrimaryKey(stepId);
                singleWorkStep.setStepId(UniqueUtil.uuid());
                singleWorkStep.setVersion(versionNumber);
                singleWorkStep.setCreateTime(DateUtil.DateToString(new Date(), DateStyle.YYYY_MM_DD_HH_MM_SS));
                singleWorkStep.setModifyTime(DateUtil.DateToString(new Date(), DateStyle.YYYY_MM_DD_HH_MM_SS));
                singleWorkSteps.add(singleWorkStep);
            }
        }
        try{
        if(singleWorkSteps!=null && singleWorkSteps.size() > 0){
            for(SingleWorkStep singleWorkStep : singleWorkSteps){
                singleWorkStepMapper.insertSelective(singleWorkStep);
            }
            resMap.put("state",RespCodeEnum.RESP_CODE_ENUM_true.code());
            resMap.put("msg","复制到该版本成功！");
        }}catch (Exception e){
            resMap.put("state",RespCodeEnum.RESP_CODE_ENUM_false.code());
            resMap.put("msg","复制到该版本失败！");
        }

        return resMap ;
    }

    /**
     * 导入步骤EXCEL
     *
     * @param
     * @param cellId
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(readOnly = false)
    public Map<String, Object> importStep(String cellId,List<SingleWorkStep> workCard,EmployeeVo employee) throws Exception {
        Map<String, Object> map = new HashMap<>();
        try{
            String creatorId = employee.getEmployeeId();
                deleteNullSteps(cellId);
                String date = DateUtil.getTimeString();
                int num = 0;
               /* int currentIndex = getCurrentNum(cellId);*/
                if (workCard != null && workCard.size() > 0) {
                    for (SingleWorkStep step : workCard) {
                        step.setStepId(UniqueUtil.uuid());
                        //上传图片
                        List<StepPic> pics = step.getPics();
                        if(pics!=null&&pics.size()>0){
                            for(StepPic pic:pics){
                                String[] names = uploadService.uploadByte("."+pic.getSuffix(), pic.getData(),applicationContext);
                                File file=new File();
                                file.setFileId(UniqueUtil.uuid());
                                file.setBusinessId(step.getStepId());
                                file.setTrait("step-img");
                                file.setFileHbasePath(names[0]);
                                fileMapper.insertSelective(file);
                            }
                        }
                        step.setModifierId(creatorId);
                        step.setModifyTime(date);
                        step.setCreatorId(creatorId);
                        step.setCreateTime(date);
                        step.setStatus(0);
                        step.setCellId(cellId);
                        map = isBlank(step);
                        num += singleWorkStepMapper.insertSelective(step);
                    }
                }
                map.put("state", num > 0 ? RespCodeEnum.RESP_CODE_ENUM_true.code() : RespCodeEnum.RESP_CODE_ENUM_false.code());
                map.put("msg", num > 0 ? BackMessage.IMPORT_OK : BackMessage.IMPORT_FAIL);
                return map;
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("数据类型不正确"+e.getLocalizedMessage());
        }
    }


    /**
     * 上移步骤、下移步骤
     * @param  singleWorkSteps
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Map<String, Object> moveStep(List<SingleWorkStep> singleWorkSteps) throws Exception {
        Map<String, Object> map = new HashMap<>();
        try {
            if( singleWorkSteps != null && singleWorkSteps.size() >0 ){
                int stepIndex = 1;
                for(SingleWorkStep singleWorkStep : singleWorkSteps){
                    singleWorkStep.setStepIndex(stepIndex);
                    singleWorkStepMapper.updateByPrimaryKeySelective(singleWorkStep);
                    stepIndex ++ ;
                }
            }
            map.put("state",RespCodeEnum.RESP_CODE_ENUM_true.code());
            map.put("msg",BackMessage.MOVE_OK);
        } catch (Exception e) {
            map.put("state",RespCodeEnum.RESP_CODE_ENUM_false.code());
            map.put("msg",BackMessage.MOVE_FAIL);
            e.printStackTrace();
        }
        return map;
    }

    /**
     * @param version 当前版本基本信息
     * @param oldVersion 当前在用版本号
     */
    @Transactional(propagation = Propagation.REQUIRED)
    @Override
    public Map<String, Object> cloneStep(Version version, BigDecimal oldVersion,Employee employee) throws Exception {
        try {
            SingleWorkStep singleWorkStep = new SingleWorkStep();
            List<SingleWorkStep> list = Lists.newArrayList();
            singleWorkStep.setCellId(version.getRelatedId());
            System.out.println("步骤版本保存 ======================================");
            list = singleWorkStepMapper.queryCellVersion(version.getRelatedId());
            singleWorkStep.setVersion(version.getVersionNumber());
            // 判断步骤的当前操作是否为空， 如果有空的则查询更新操作步骤版本
            if(list!=null && list.size() > 0){
                singleWorkStepMapper.updateWorkCellInfoVersion(singleWorkStep);
            }else{
                // 存在版本，版本有操作步骤
                SingleWorkStep sw=new SingleWorkStep();
                sw.setCellId(version.getRelatedId());
                sw.setVersion(oldVersion);
                List<SingleWorkStep> singleWorkSteps = singleWorkStepMapper.selectByStep(sw);
                String creatorId = employee.getEmployeeId();
                if(singleWorkSteps != null && singleWorkSteps.size() > 0) {
                        for (SingleWorkStep s : singleWorkSteps) {
                            String oldStep = s.getStepId();
                            s.setStepId(UniqueUtil.uuid());
                            s.setCreatorId(creatorId);
                            s.setCreateTime(DateUtil.getTimeString());
                            s.setModifierId(creatorId);
                            s.setModifyTime(DateUtil.getTimeString());
                            s.setStatus(0);
                            s.setVersion(version.getVersionNumber());
                            singleWorkStepMapper.insertSelective(s);
                            //保存步骤对应的数据项
                            List<SingleWorkStepDataItem> dataItems = singleWorkService.getDataItemByStepId(oldStep);
                            if (dataItems != null && dataItems.size() > 0) {
                                for (SingleWorkStepDataItem dataItem : dataItems) {
                                    dataItem.setDataItemId(UniqueUtil.uuid());
                                    dataItem.setCreatorId(creatorId);
                                    dataItem.setCreatTime(DateUtil.getTimeString());
                                    dataItem.setModifierId(creatorId);
                                    dataItem.setStatus(new BigDecimal(0));
                                    dataItem.setModifyTime(DateUtil.getTimeString());
                                    dataItem.setStepId(s.getStepId());
                                    singleWorkService.addDataItem(dataItem);
                                }
                            }

                            fileService.cloneInsert(oldStep,s.getStepId());
                        }


                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param workCellInfo 操作单元
     * @param workCellInstance 一站一案
     * 一站一案 新增带入操作单元的步骤
     */
    @Override
    public Map<String, Object> cloneStep(WorkCellInfo workCellInfo, WorkCellInstance workCellInstance,Employee employee) throws Exception {
        // 复制步骤
        SingleWorkStep singleWorkStep=new SingleWorkStep();
        if (workCellInfo != null && workCellInfo.getStepVersion() != null) {
            singleWorkStep.setCellId(workCellInfo.getCellId());
            singleWorkStep.setVersion(workCellInfo.getStepVersion());
            // 查询操作单元当前步骤
            List<SingleWorkStep> singleWorkSteps = singleWorkStepMapper.selectByStep(singleWorkStep);
            //保存对应的操作单元的步骤
            String creatorId = employee.getEmployeeId();
            // 判断操作步骤是否为空
            if (singleWorkSteps != null && singleWorkSteps.size() > 0) {
                for (SingleWorkStep s : singleWorkSteps) {
                    String oldStepId = s.getStepId();
                    s.setCellId(workCellInstance.getWorkInstanceId());
                    s.setStepId(UniqueUtil.uuid());
                    s.setCreateTime(DateUtil.getTimeString());
                    s.setCreatorId(creatorId);
                    s.setModifyTime(DateUtil.getTimeString());
                    s.setModifierId(creatorId);
                    s.setWorkContentId(workCellInstance.getWorkInstanceId());
                    s.setVersion(null);
                    singleWorkStepMapper.insertSelective(s);
                    //保存步骤对应的数据项
                    List<SingleWorkStepDataItem> dataItems = singleWorkService.getDataItemByStepId(oldStepId);
                    if (dataItems != null && dataItems.size() > 0) {
                        for (SingleWorkStepDataItem dataItem : dataItems) {
                            dataItem.setDataItemId(UniqueUtil.uuid());
                            dataItem.setCreatorId(creatorId);
                            dataItem.setCreatTime(DateUtil.getTimeString());
                            dataItem.setModifierId(creatorId);
                            dataItem.setStatus(new BigDecimal(0));
                            dataItem.setModifyTime(DateUtil.getTimeString());
                            dataItem.setStepId(s.getStepId());
                            singleWorkService.addDataItem(dataItem);
                        }
                    }
                    fileService.cloneInsert(oldStepId,s.getStepId());
                }
            }
        }
        return null;
    }

    /**
     * @param oldInstance 原来一站一案基本信息
     * @param newInstance 新一站一案基本信息
     * @param employeeVo 复制人员基本信息
     */
    @Override
    public Map<String, Object> cloneStep(WorkCellInstance oldInstance, WorkCellInstance newInstance, EmployeeVo employeeVo) throws Exception {
      Map<String,Object> resMap = new HashMap<>();
      // 判断原来一站一案
      if(StringUtils.isNotEmpty(oldInstance.getStepVersion()+"")){
          List<SingleWorkStep> singleWorkStep = singleWorkStepMapper.queryStepByWorkCellInstanceId(oldInstance) ;
          if(singleWorkStep != null && singleWorkStep.size() > 0){
                for(SingleWorkStep workStep : singleWorkStep){
                    String newStepId = UniqueUtil.uuid() ;
                    // 查询 file ;
                    List<File>  fileList = fileMapper.queryByBusinessId(workStep.getStepId());
                    if(fileList != null && fileList.size() > 0){
                        for(File file : fileList){
                            file.setFileId(UniqueUtil.uuid());
                            file.setBusinessId(newStepId);
                            fileMapper.insertSelective(file);
                        }
                    }
                    workStep.setStepId(newStepId);
                    workStep.setCellId(newInstance.getWorkInstanceId());
                    workStep.setVersion(null);
                    workStep.setCreatorId(employeeVo.getEmployeeId());
                    workStep.setModifierId(employeeVo.getEmployeeId());
                    workStep.setCreateTime(DateUtil.DateToString(new Date(),DateStyle.YYYY_MM_DD_HH_MM));
                    workStep.setModifyTime(DateUtil.DateToString(new Date(),DateStyle.YYYY_MM_DD_HH_MM));
                    singleWorkStepMapper.copySelective(workStep);
                }
          }
          resMap.put("state",true);
          resMap.put("msg","复制步骤成功！");
      }else{
          resMap.put("state",true);
          resMap.put("msg","未找到步骤具有版本的步骤信息");
      }
      return resMap ;
    }


    /*
   ------------以下是数据项操作方法------------------------------------------------------------------
     */

    /**
     * 获取数据项明细list
     *
     * @param stepId
     * @return
     * @throws Exception
     */
    @Override
    public List<SingleWorkStepDataItem> getDataItem(String stepId){
        return singleWorkService.getDataItemByStepId(stepId);
    }

    /**
     * 批量添加数据项
     *
     * @param dataItem
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Map<String, Object> addDataItem(SingleWorkStepDataItem[] dataItem,Employee employee) throws Exception {
        //设置创建人ID
        String creatorId = employee.getEmployeeId();
        Map<String, Object> map = new HashMap<>();
        //对数据项参数进行校验
        for (int i = 0; i < dataItem.length; i++) {
            if ((Boolean) singleWorkService.isBlank(dataItem[i]).get("state") == RespCodeEnum.RESP_CODE_ENUM_false.code())
                return map;
        }
        int num = 0;
        //对数据项数组进行循环
        for (int i = 0; i < dataItem.length; i++) {
            String dataItemId = UniqueUtil.uuid();
            dataItem[i].setDataItemId(dataItemId);
            dataItem[i].setCreatorId(creatorId);
            dataItem[i].setCreatTime(DateUtil.getTimeString());
            dataItem[i].setStatus(new BigDecimal(0));
            map = singleWorkService.addDataItem(dataItem[i]);
            //某个数据项添加失败，即手动回滚事务，并返回信息
            if ((Boolean) map.get("state") == RespCodeEnum.RESP_CODE_ENUM_false.code()) {
                //手动回滚事务
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return map;
            }
            num++;
        }
        map.put("msg", num > 0 ? BackMessage.ADD_OK : BackMessage.ADD_FAIL);
        return map;
    }

    /**
     * 修改数据项
     *
     * @param dataItem
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Map<String, Object> modifyDataItem(SingleWorkStepDataItem dataItem,Employee employee) throws Exception {
        String modifierId = employee.getEmployeeId();
        Map<String, Object> map = new HashMap<>();
        int num = 0;
        //对数据项参数进行校验
        if ((Boolean) singleWorkService.isBlank(dataItem).get("state") == RespCodeEnum.RESP_CODE_ENUM_false.code())
            return map;
        //设置修改人ID及修改时间
        dataItem.setModifierId(modifierId);
        dataItem.setModifyTime(DateUtil.getTimeString());
        //修改数据项
        map = singleWorkService.modifyDataItemExpValidate(dataItem);
        if (map.get("state") != null && (Boolean) map.get("state") == RespCodeEnum.RESP_CODE_ENUM_false.code()) {
            //手动回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return map;
        }
        map.put("state", RespCodeEnum.RESP_CODE_ENUM_true.code());
        return map;
    }

    /**
     * 删除数据项
     *
     * @param dataItemId
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public Map<String, Object> delDataItem(String dataItemId) throws Exception {
        return singleWorkService.delDataItem(dataItemId);
    }
    /**
     *  根据操作单元或者一站一案查询当前版本的步骤 和 新增的步骤
     * @param  version
     * @param isWorkCell
     * @throws Exception
     */
    @Override
    public Map<String, Object> cloneStepVersion(Version version, boolean isWorkCell,Employee employee) throws Exception {
        Map resMap = new HashMap<>();
        SingleWorkStep singleWorkStep = new SingleWorkStep();
        /**
         * 设置版本需要设置当前正在用的，然后再查询
         */
        if(isWorkCell){
            singleWorkStep.setCellId(version.getRelatedId());
            WorkCellInfo  workCellInfo = workCellInfoMapper.selectByPrimaryKey(version.getRelatedId());
            singleWorkStep.setVersion(workCellInfo.getStepVersion());
        }else{
          WorkCellInstanceVo workCellInstanceVo =  workCellInstanceMapper.queryInstanceInfoUnionById(version.getRelatedId());
            singleWorkStep.setWorkContentId(version.getRelatedId());
            singleWorkStep.setVersion(workCellInstanceVo.getStepVersion());
        }
        List<SingleWorkStep> oldVersionStepList = singleWorkStepMapper.selectByStep(singleWorkStep);
        if(oldVersionStepList!=null && oldVersionStepList.size() > 0){
            String creatorId = employee.getEmployeeId();
            for(SingleWorkStep step : oldVersionStepList){
                String oldStepId = step.getStepId();
                step.setCreatorId(creatorId);
                step.setModifierId(creatorId);
                step.setModifyTime(DateUtil.DateToString(new Date(), DateStyle.YYYY_MM_DD_HH_MM_SS));
                step.setCreateTime(DateUtil.DateToString(new Date(), DateStyle.YYYY_MM_DD_HH_MM_SS));
                if(step.getVersion()!=null) {
                    step.setStepId(UniqueUtil.uuid());
                    step.setVersion(version.getVersionNumber());
                    singleWorkStepMapper.insertSelective(step);
                }else{
                    step.setVersion(version.getVersionNumber());
                    singleWorkStepMapper.updateByPrimaryKeySelective(step);
                }

                // 克隆图片
                fileService.cloneInsert(oldStepId,step.getStepId());

            }
        }else{
            resMap.put("state",RespCodeEnum.RESP_CODE_ENUM_false.code());
            resMap.put("state","暂无操作步骤");
        }
        return null;
    }

    /**
     * 根据操作单元删除步骤
     */
    @Override
    @Transactional(readOnly = false)
    public Map<String,Object> delStepByCellId(String cellId) throws Exception {
        Map<String,Object> result= Maps.newHashMap();
        try{
            singleWorkStepMapper.delStepByCellId(cellId);
            result.put("state", RespCodeEnum.RESP_CODE_ENUM_true.code());
            result.put("msg","删除步骤成功");
            return  result;
        }catch (Exception e){
            throw new RuntimeException("删除步骤出错");
        }
    }

    /***
     * 根据阶段删除步骤
     *
     * @param type
     * @param stepId
     * @return
     */
    @Override
    @Transactional(readOnly =  false)
    public  Map<String,Object> delStepByStepId(Integer type, String stepId) throws  Exception {
        Map<String,Object> result= Maps.newHashMap();
        try {
            SingleWorkStep singleWorkStep=new SingleWorkStep();
            singleWorkStep.setStepId(stepId);
            singleWorkStep.setStepType(type);
            singleWorkStepMapper.delStepByStepId(singleWorkStep);
            List<SingleWorkStep> singleWorkSteps = singleWorkStepMapper.selectByStepSelect(singleWorkStep);
            int index=1;
            for(SingleWorkStep s:singleWorkSteps){
                s.setStepIndex(index++);
                singleWorkStepMapper.updateByPrimaryKeySelective(s);
            }
            result.put("state", RespCodeEnum.RESP_CODE_ENUM_true.code());
            result.put("msg","删除步骤成功");
            return  result;
        }catch (Exception e){
            throw  new RuntimeException("删除步骤失败");
        }

    }

    /**
     * 添加步骤
     *
     * @param singleWorkSteps
     * @param cellId
     * @return
     * @throws Exception
     */
    @Override
    public Map<String,Object> addStep(List<SingleWorkStep> singleWorkSteps,String cellId,Employee employee) throws Exception {
        Map<String,Object> result=Maps.newHashMap();
        try{
            String creatorId = employee.getEmployeeId();
            JSONArray array= new JSONArray();
            List<SingleWorkStepDataItem> list;
            SingleWorkStepDataItem stepDataItem;
            SingleWorkStepDataItem[] singleWorkStepDataItem;
            // 删除版本为空的步骤及相关信息(当前正在编辑的版本)
            deleteNullSteps(cellId);
            // 临时保存这些步骤
            if( singleWorkSteps != null && singleWorkSteps.size() > 0 ){
                for(SingleWorkStep singleWorkStep:singleWorkSteps){
                    // 步骤的基本信息
                    singleWorkStep.setCreateTime(DateUtil.getTimeString());
                    singleWorkStep.setModifierId(creatorId);
                    singleWorkStep.setStepId(UniqueUtil.uuid());
                    singleWorkStep.setCreatorId(creatorId);
                    singleWorkStep.setModifyTime(DateUtil.getTimeString());
                    singleWorkStep.setStatus(0);
                    singleWorkStep.setVersion(null);
                    // 保存上传图像
                    fileService.addFile(singleWorkStep.getUploadFiles(), singleWorkStep.getDeletedFiles(),singleWorkStep.getStepId());
                    // 保存数据项
                    if(StringUtils.isNotBlank(singleWorkStep.getDataItem()) ){
                        try{
                            singleWorkService.batchAddDataItem(singleWorkStep,employee);
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                    singleWorkStepMapper.insertSelective(singleWorkStep);
                }
            }
            result.put("state",RespCodeEnum.RESP_CODE_ENUM_true.code());
            result.put("msg",  BackMessage.ADD_OK );
            return result;
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("保存步骤失败");
        }

    }

    /**
     * 删除空版本的步骤
     * @param cellId
     * @return
     */
    //@Transactional(propagation = Propagation.REQUIRED)
    private void deleteNullSteps(String cellId){
        // 查询版本号为null的操作单元步骤(当前正在编辑的版本)
        List<SingleWorkStep> list = singleWorkStepMapper.queryCellVersion(cellId);
        if( list != null && list.size() > 0 ){
            // 删除这些步骤的图片
            fileMapper.deleteStepFiles(list);
            // 删除这些步骤的数据项
            singleWorkStepDataItemMapper.deleteStepDataItem(list);
            // 删除这些步骤
            singleWorkStepMapper.deleteSteps(list);
        }
    }

    /**
     * 构造步骤信息
     * @param list
     * @return
     */
    public List<SingleWorkStep> createStep(List<SingleWorkStep> list){
        List<SingleWorkStep> newList = list;
        if(  list != null && list.size() > 0 ){
            newList = new ArrayList<>();
            for( SingleWorkStep step:list ){
                List<File> files = fileMapper.queryByBusinessId(step.getStepId());
                // 步骤图片
                if (files != null && files.size() > 0) {
                    step.setUploadFiles(JSON.toJSONString(files));
                }
                // 数据项
                List<SingleWorkStepDataItem> singleWorkStepDataItems = getDataItem(step.getStepId());
                // add by huangxueqian 2017-12-27 新增对接手工录入平台
                List<SingleWorkStepDataItem> thisDataItemArray = new ArrayList<>() ;
                List<SingleWorkStepDataItem> otherDataItemArray = new ArrayList<>() ;
                if(singleWorkStepDataItems!=null && singleWorkStepDataItems.size() > 0){
                    for(SingleWorkStepDataItem dataItem:singleWorkStepDataItems){
                        if(dataItem.getItemType().floatValue() == 0){
                            otherDataItemArray.add(dataItem); // 接入其他系统的数据项
                        }else{
                            thisDataItemArray.add(dataItem);  // 本地数据项
                        }
                    }
                }
                JSONObject dataObj = new JSONObject();
                dataObj.put("thisDataItem",thisDataItemArray);
                if(otherDataItemArray != null && otherDataItemArray.size() > 0){
                  List<SingleWorkStepDataItem>  resList =  singleWorkService.offsetList(otherDataItemArray);
                    dataObj.put("otherDataItem",resList);
                }

                if (singleWorkStepDataItems != null && singleWorkStepDataItems.size() > 0) {
                    step.setDataItem(JSON.toJSONString(dataObj));
                }
                newList.add(step);
            }
        }
        return newList;
    }

    /**
     * 得到操作单元的操作步骤
     * @param    cellId      操作单元 id 或者一站一案 id
     * @param    stepVersion 当前步骤版本
     * @param    isStatus    当前状态
     * @param    backTarget  标识{一站一案或者操作单元}
     */
    @Override
    public List<SingleWorkStep> getStepByCellId(String cellId,String stepVersion,String isStatus,String backTarget) {
        try{
            SingleWorkStep singleWorkStep=new SingleWorkStep();
            if("details".equals(isStatus)){
                singleWorkStep.setVersion(new BigDecimal(stepVersion));
                singleWorkStep.setCellId(cellId);
                return createStep(singleWorkStepMapper.selectByStep(singleWorkStep));
            }else{
                // 查询版本号为null的操作单元步骤(当前正在编辑的版本)
                List<SingleWorkStep> nullList = singleWorkStepMapper.queryCellVersion(cellId);
                if (  nullList != null && nullList.size() > 0 ){
                    return createStep(nullList);
                }else{
                    Version version = versionService.queryMaxVersion(cellId);
                    List<SingleWorkStep> list = singleWorkStepMapper.queryCellVersion(cellId);
                    if(list !=null&&list.size()>0){
                        singleWorkStep.setVersion(null);
                    }else{
                        if(version!=null&&version.getVersionNumber()!=null){
                            singleWorkStep.setVersion(version.getVersionNumber().setScale(2,BigDecimal.ROUND_HALF_UP));
                        }
                    }
                    singleWorkStep.setCellId(cellId);
                    return createStep(singleWorkStepMapper.selectByStep(singleWorkStep));
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return  null;
    }

    /**
     * 根据cellId和版本查询步骤
     * @param singleWorkStep
     * @return
     */
    @Override
    public List<SingleWorkStep> getStepsByCellIdAndVersion(SingleWorkStep singleWorkStep) {
        return singleWorkStepMapper.selectByStep(singleWorkStep);
    }

    /**
     * 分析操作卡情况
     * @param singleWorkStep
     * @return
     */
    @Override
    public List<SingleWorkStep> getAnalysisSteps(SingleWorkStep singleWorkStep, int longgestStep) {
        List<SingleWorkStep> list = singleWorkStepMapper.selectByStep(singleWorkStep);
        List<SingleWorkStep> newList = new ArrayList<>();
        List<File> files;
        int avg;
        if( list != null && list.size() > 0 ){
            for ( SingleWorkStep s: list){
                files = fileMapper.queryByBusinessId(s.getStepId());
                if( files != null && files.size() > 0 ){
                    s.setHasPic(files.size());
                }else{
                    s.setHasPic(0);
                }
                avg = singleWorkStepMapper.getAvgByStepId(s.getStepId());
                if( avg > longgestStep ){
                    longgestStep = avg;
                }
                s.setAvgExecuteDuring(avg);
                newList.add(s);
            }
        }
        return newList;
    }



    /*
    ------------以下是私有方法--------------------------------------------------------------------------------
     */

    /**
     * 获取上级或下级步骤对象
     * direction=“prev” 当前步骤前的
     * direction=“after”当前步骤后的
     * @param stepId
     */
    private SingleWorkStep getStepBA(String stepId, String direction) throws Exception {
        SingleWorkStep step = singleWorkStepMapper.selectByPrimaryKey(stepId);
        int index = step.getStepIndex();
        String cellId = step.getCellId();
        int num = 0;
        if (cellId != null) {
            SingleWorkStep stept = new SingleWorkStep();
            stept.setCellId(cellId);
            num = singleWorkStepMapper.selectCountByStep(stept);
            if ("prev".equals(direction)) {
                if (index <= 1) return null;
                SingleWorkStep step1 = new SingleWorkStep();
                step1.setCellId(cellId);
                step1.setStepIndex(index - 1);
                return singleWorkStepMapper.selectByStepSelect(step1).get(0);
            } else {
                if (index >= num) return null;
                SingleWorkStep step1 = new SingleWorkStep();
                step1.setCellId(cellId);
                step1.setStepIndex(index + 1);
                return singleWorkStepMapper.selectByStepSelect(step1).get(0);
            }
        }
        return null;
    }

    /**
     * 获取当前步骤后面的所有步骤
     *
     * @param stepId
     * @return
     * @throws Exception
     */
    private List<SingleWorkStep> getAfterSteps(String stepId) throws Exception {
        SingleWorkStep step = singleWorkStepMapper.selectByPrimaryKey(stepId);
        int index = step.getStepIndex();
        String cellId = step.getCellId();
        return null ;//stepMapper.selectByBigThanIndexByCellId(index, cellId);
    }

    /**
     * 批量步骤下移
     *
     * @param stepList
     * @return
     */
    private Integer udpateIndexDownByList(List<SingleWorkStep> stepList) throws Exception {
        int num = 0;
        if (stepList != null && stepList.size() > 0) {
            for (SingleWorkStep step : stepList) {
                num += singleWorkStepMapper.updateIndex(step.getStepIndex() + 1, step.getStepId());
            }
        }
        return num;
    }

    /**
     * 获取当前操作单元使用步骤的数量
     *
     * @param cellId
     * @return
     */
    private Integer getCurrentNum(String cellId) {
        SingleWorkStep step = new SingleWorkStep();
        step.setCellId(cellId);
        return singleWorkStepMapper.selectCountByStep(step);
    }

    /**
     * 为每个步骤设置上级步骤名称
     * @param stepList
     * @return
     * @throws Exception
     */
    private void setParentName(List<SingleWorkStep> stepList) throws Exception {
        if (stepList != null && stepList.size() > 0) {
            for (int i = 0; i < stepList.size(); i++) {
                SingleWorkStep prevStep = null;
                if (i > 0) {
                    prevStep = stepList.get(i - 1);
                }
                stepList.get(i).setStepTypeName(getStepTypeName(stepList.get(i).getStepType()));
                stepList.get(i).setParentStepName(prevStep == null ? null : prevStep.getStepName());
            }
        }
    }

    /**
     * 转换步骤分类：准备阶段；操作阶段；收尾阶段；
     * @param stepTypeId
     * @return
     */
    private String getStepTypeName(Integer stepTypeId) {
        if (stepTypeId != null) {
            for (StepStage ss : StepStage.values()) {
                if (ss.getCode() == stepTypeId) {
                    return ss.getDesc();
                }
            }
        }
        return null;
    }

    /**
     * 对SingleWorkStep参数进行判空
     *
     * @param singleWorkStep
     * @return
     */
    private Map<String, Object> isBlank(SingleWorkStep singleWorkStep) {
        Map<String, Object> map = new HashedMap();
        map.put("state", RespCodeEnum.RESP_CODE_ENUM_false.code());
        if (StringUtils.isBlank(singleWorkStep.getStepId())) {
            map.put("msg", "ID不能为空");
            return map;
        }
        if (StringUtils.isBlank(singleWorkStep.getStepName())) {
            map.put("msg", "步骤名不能为空");
            return map;
        }
        if (singleWorkStep.getStepName().length() > 100) {
            map.put("msg", "步骤名长度不能超过100");
            return map;
        }
        if (StringUtils.isBlank(singleWorkStep.getControlMeasures())) {
            map.put("msg", "控制措施不能为空！");
            return map;
        }
        if (StringUtils.isBlank(singleWorkStep.getPotentialRisk())) {
            map.put("msg", "潜在风险不能为空！");
            return map;
        }
        map.put("state", RespCodeEnum.RESP_CODE_ENUM_true.code());
        return map;
    }
}
